////////////////////////////////////////////////////////////////////
// Programme d'ajout/suppression d'auto-accents de Chrono Cross
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// Nemesis pour Terminus Traduction (tt_nemesis@yahoo.fr)
// Date de création :		03/05/04
// Dernière modification :	23/04/04
////////////////////////////////////////////////////////////////////

// Entete
#include "AutoAccents.h"

// Pointeur rencontré ou pas
int AutoA_Ptr;

// Types de données pour la table
// (Beuhhh j'occupe la mémoire)
typedef struct {
	char *chaine;	// sans accent
	char *chaine_a;	// avec accent
	int long_c;
	char *motifs[AUTOA_MOTIFS_NB]; // motifs de reconnaissance
	int position[AUTOA_MOTIFS_NB]; // position de l'élément dans le motif
	int motifs_nb;
} AutoA_TElement;

// Table de caractères
static AutoA_TElement AutoA_table[AUTOA_ELMTS_NB];
static int AutoA_table_nb=0;

/*------------------------------------------------------------------
  Chargement d'une table d'accents
--------------------------------------------------------------------
 <- nom = fichier table à ouvrir
 <- inout = AUTOA_IN ou AUTOA_OUT déterminant le dossier de la table
------------------------------------------------------------------*/
void AutoA_Charge(int inout)
{
	// Fichier table
	FILE *table_f;
	char fichier[AUTOA_NOM_MAX];
	unsigned _int8 p;
	// Ligne du fichier table
	char ligne[AUTOA_LIGNE_MAX];
	// Nombre de motifs
	int motifs_nb;
	// Position dans le motif
	int position;
	// Chaîne temporaire
	char temp[AUTOA_LIGNE_MAX];

	// Ouverture du fichier
	if (inout==AUTOA_IN)
		sprintf(fichier,"%s%s.%s",DIR_TABLES_IN,AUTO_ACCENTS,EXT_ACCENT);
	else
		sprintf(fichier,"%s%s.%s",DIR_TABLES_OUT,AUTO_ACCENTS,EXT_ACCENT);
	table_f=fopen(fichier, "rt");
	if (table_f!=NULL) {
		// Parcours de la table de caractères
		while(fgets(ligne,AUTOA_LIGNE_MAX,table_f)!=NULL) {
			// Test de commentaire
			if (ligne[0]!=COMMENT) {
				// Elimination du retour chariot
				ligne[strlen(ligne)-1]=0;
				sscanf(ligne,"%02d ",&motifs_nb);
				AutoA_table[AutoA_table_nb].motifs_nb=motifs_nb;
				// Séparation chaine d'origine/avec accent
				AutoA_table[AutoA_table_nb].chaine_a=
					strdup(strtok_cc(&ligne[3],AUTOA_EGALE));
				AutoA_table[AutoA_table_nb].chaine=strdup(&ligne[3]);
				AutoA_table[AutoA_table_nb].long_c=
					strlen(AutoA_table[AutoA_table_nb].chaine);
				// Listing des patterns
				for (p=0;p<AutoA_table[AutoA_table_nb].motifs_nb;p++) {
					fgets(ligne,AUTOA_LIGNE_MAX,table_f);
					ligne[strlen(ligne)-1]=0;
					sscanf(&ligne[1],"%02d ",&position);
					AutoA_table[AutoA_table_nb].position[p]=position;
					AutoA_table[AutoA_table_nb].motifs[p]=
						strdup(&ligne[4]);
				}
				// Cas où il n'y a aucun motif
				if (AutoA_table[AutoA_table_nb].motifs_nb==0) {
					// On en crée un toujours actif
					AutoA_table[AutoA_table_nb].motifs_nb++;
					AutoA_table[AutoA_table_nb].position[0]=2;
					sprintf(temp,"%c%s%c", AUTOA_SNIMPORTE,
						AutoA_table[AutoA_table_nb].chaine,
						AUTOA_SNIMPORTE);
					AutoA_table[AutoA_table_nb].motifs[0]=strdup(temp);
				}
			};
			AutoA_table_nb++;
		};
		fclose(table_f);
	} else
		Main_Message_S("Impossible d'ouvrir la table\n","",ER);
}

/*------------------------------------------------------------------
  Libération mémoire de la table d'accents
------------------------------------------------------------------*/
void AutoA_Libere(void)
{
	// Indice dans la table
	int i,p;

	// Libération des chaînes de caractères
	for(i=0;i<AutoA_table_nb;i++) {
		// Liberation des motifs
		for(p=0;p<AutoA_table[i].motifs_nb;p++) {
			if (AutoA_table[i].motifs[p]!=NULL) {
				free(AutoA_table[i].motifs[p]);
				AutoA_table[i].motifs[p]=NULL;
				AutoA_table[i].position[p]=0;
			};
			AutoA_table[i].long_c=0;
		}
		if (AutoA_table[i].chaine!=NULL) {
			free(AutoA_table[i].chaine);
			AutoA_table[i].chaine=NULL;
		}
		if (AutoA_table[i].chaine_a!=NULL) {
			free(AutoA_table[i].chaine_a);
			AutoA_table[i].chaine_a=NULL;
		}
		AutoA_table[i].motifs_nb=0;
	}
	AutoA_table_nb=0;
}

/*------------------------------------------------------------------
  Lecture d'une ligne accentuée
--------------------------------------------------------------------
 <- ligne = ligne accentuée
 <- out_f = fichier dans lequel on écrit le texte correspondant
------------------------------------------------------------------*/
void AutoA_Supprime_Ligne(char *ligne, FILE *out_f)
{
	// Position dans la chaîne
	unsigned int pos=0;
	// Longueur de la chaîne
	unsigned int l=strlen(ligne);
	// Adresse dans la chaîne de l'élément
	char *adresse1=ligne;
	char *adresse2;
	// Index de recherche et de trouvaille ^^
	int i;

	// Parcours de la chaîne
	while(adresse1!=NULL) {
		// Traitement des lettres
		// Cas d'un code dès le départ
		adresse2=strtok_cc(adresse1,AUTOA_SPEC);
		if (adresse1!=NULL && adresse1[0]!=0)
			fputs(adresse1,out_f);
		// Traitement des codes
		adresse1=strtok_cc(adresse2,AUTOA_SPEC);
		if (adresse2!=NULL && adresse2[0]!=0) {
			// Parcours de la table
			for(i=0;
				i<AutoA_table_nb && strcmp(AutoA_table[i].chaine_a,adresse2)!=0;
				i++);
			// Ecriture effective
			if (i<AutoA_table_nb)
				fputs(AutoA_table[i].chaine,out_f);
			else
				fprintf(out_f,"%c%s%c",
					AUTOA_SPEC,adresse2,AUTOA_SPEC);	
		}
	};
}

/*------------------------------------------------------------------
  Suppression des accents automatiques dans un script dégroupé
------------------------------------------------------------------*/
void AutoA_Supprime ()
{
	// Fichiers entrants et sortants
	FILE *in_f,*out_f;
	char fich_nom[AUTOA_NOM_MAX];
	// Indice
	int i;
	// Ligne du script
	char ligne[AUTOA_LIGNE_MAX];

	Main_Message_S("Suppression des accents automatiques...","",OK);

	// Ouverture du fichier d'origine
	sprintf(fich_nom,"%s%s%s%s%s.%s",
		DIR_TXT_IN,DIR_TXT_REP,AUTOA_SCRIPT,CD_SUFFIXE,AUTOA_TRAD,EXT_TXT);
	in_f=fopen(fich_nom,"r");

	// Copie effective sans accents
	if (in_f==NULL)
		Main_Message_S("Script introuvable.\n","",ER);
	else {
		// Chargement des infos
		AutoA_Charge(AUTOA_IN);
		// Ouverture du fichier de sortie
		sprintf(fich_nom,"%s%s%s%s%s%s.%s",
			DIR_TXT_IN,DIR_TXT_REP,AUTOA_SCRIPT,CD_SUFFIXE,AUTOA_TRAD,AUTOA_ACCENTS,EXT_TXT);
		out_f=fopen(fich_nom,"w");
		// Recopie de l'entête du script
		for(i=0;i<4;i++) {
			fgets(ligne,AUTOA_LIGNE_MAX,in_f);
			fputs(ligne,out_f);
		}
		fgets(ligne,AUTOA_LIGNE_MAX,in_f);
		// Parcours du fichier
		while(!feof(in_f)) {
			// Attente d'un bloc à traduire
			while(!feof(in_f) && ligne[0]!=AUTOA_TRAD_CAR)
				fgets(ligne,AUTOA_LIGNE_MAX,in_f);
			if (!feof(in_f)) {
				// Parcours du bloc à réduire
				fputs(ligne,out_f);
				// Ligne de configuration de la fenêtre
				fgets(ligne,AUTOA_LIGNE_MAX,in_f);
				fputs(ligne,out_f);
				fgets(ligne,AUTOA_LIGNE_MAX,in_f);
			}
			while(!feof(in_f) && ligne[0]==AUTOA_DEB_A) {
				AutoA_Supprime_Ligne(ligne,out_f);
				fgets(ligne,AUTOA_LIGNE_MAX,in_f);
			}
		}
		// Fermeture des fichiers
		fclose(in_f);
		fclose(out_f);
		Main_OK();
	}
}

/*------------------------------------------------------------------
  Comparaison de chaînes avec tokens
  (On suppose que les paramètres sont corrects, temps perdu lourd)
--------------------------------------------------------------------
 <- motif = motif à matcher
 <- chaine = chaine à tester
 <- debut = position d'analyse
------------------------------------------------------------------*/
int strncmp_cc(char *motif, char *chaine, int debut)
{
	// Position courante
	int pos=0;

	// Parcours du motif
	while (motif[pos]!=0) {
		// Test d'erreur -> fin de chaîne
		if (chaine[debut]==0)
			return ER;
		// Matching
		switch (motif[pos]) {
		case AUTOA_SLETTRE:
			// Erreur si séparateur
			if (strchr(AUTOA_SEPAR,chaine[debut])!=NULL)
				return ER;
			break;
		case AUTOA_SCONSONNE:
			// Erreur si non consonne
			if (strchr(AUTOA_CONSONNE,chaine[debut])==NULL)
				return ER;
			break;
		case AUTOA_SVOYELLE:
			// Erreur si non voyelle
			if (strchr(AUTOA_VOYELLE,chaine[debut])==NULL)
				return ER;
			break;
		case AUTOA_SSEPAR:
			// Erreur si non séparateur
			if ((pos!=0 || debut!=AUTOA_DEBUT)
				&& strchr(AUTOA_SEPAR,chaine[debut])==NULL)
				return ER;
			break;
		case AUTOA_SNIMPORTE:
			// Tout caractère fonctionne
			break;
		default:
			// Erreur si lettre différente
			if (motif[pos]!=chaine[debut])
				return ER;
		}
		debut++;
		pos ++;
	}

	return OK;
}

/*------------------------------------------------------------------
  Ecriture et insertion d'accents dans une ligne
--------------------------------------------------------------------
 <- ligne = ligne non accentuée
 <- out_f = fichier dans lequel on écrit le texte correspondant
------------------------------------------------------------------*/
void AutoA_Insere_Ligne(char *ligne, FILE *out_f)
{
	// Position dans la chaîne
	int pos=1;
	// Longueur de la chaîne
	int l=strlen(ligne);
	// Indice de recherche
	int i,p;
	// "Meilleurs" indices
	int i_max,p_max;
	int long_max;

	// Modification du début
	ligne[0]=' '; // séparateur par défaut
	// Parcours de la chaîne
	fputc(AUTOA_DEB_A,out_f);
	while(ligne!=NULL && ligne[pos]!=0) {
		// Cas d'une balise
		if (ligne[pos]==AUTOA_SPEC) {
			do {
				fputc(ligne[pos],out_f);
				pos++;
			} while (ligne[pos]!=AUTOA_SPEC);
			fputc(ligne[pos],out_f);
			pos++;
		} else {
			// Gestion des majuscules
			if (ligne[pos]>='A' && ligne[pos]<='Z') {
				ligne[pos]+='a'-'A';
				fprintf(out_f,"%c%s%c",AUTOA_SPEC,AUTOA_MAJ,AUTOA_SPEC);
			}
			// Recherche d'un motif correspondant dans la table
			long_max=0;
			for(i=0;i<AutoA_table_nb;i++) {
				for(p=0;p<AutoA_table[i].motifs_nb;p++)
					if (AutoA_table[i].long_c>long_max
						&& strncmp_cc(AutoA_table[i].motifs[p],
						ligne,pos-AutoA_table[i].position[p]+1)==OK) {
						// Motif trouvé => mémorisation
						long_max=AutoA_table[i].long_c;
						i_max=i;
						p_max=p;
					}
			}
			// Ecriture
			if (long_max>0) {
				// Inscription du code
				fprintf(out_f,"%c%s%c",AUTOA_SPEC,AutoA_table[i_max].chaine_a,AUTOA_SPEC);
				pos+=AutoA_table[i_max].long_c;
			} else {
				fputc(ligne[pos],out_f);
				pos++;
			}
		}
	};
}

/*------------------------------------------------------------------
  Insertion des accents automatiques dans un script dégroupé
------------------------------------------------------------------*/
void AutoA_Insere ()
{
	// Fichiers entrants et sortants
	FILE *in_f,*orig_f,*out_f;
	char fich_nom[AUTOA_NOM_MAX];
	char fich_nom_s[AUTOA_NOM_MAX];
	char fich_nom_t[AUTOA_NOM_MAX];
	// Indice
	int i;
	// Ligne du script
	char ligne_o[AUTOA_LIGNE_MAX];
	char ligne_s[AUTOA_LIGNE_MAX];

	Main_Message_S("Insertion des accents automatiques...","",OK);

	// Changement de fichier temporairement
	sprintf(fich_nom,"%s%s%s%s%s.%s",
		DIR_TXT_OUT,DIR_TXT_REP,AUTOA_SCRIPT,CD_SUFFIXE,AUTOA_TRAD,EXT_TXT);
	sprintf(fich_nom_s,"%s%s%s%s%s%s.%s",
		DIR_TXT_OUT,DIR_TXT_REP,AUTOA_SCRIPT,CD_SUFFIXE,AUTOA_TRAD,AUTOA_TEMP,EXT_TXT);
	rename(fich_nom,fich_nom_s);
	// Ouverture du fichier d'origine
	orig_f=fopen(fich_nom_s,"r");
	// Ouverture du script sans accents
	sprintf(fich_nom_t,"%s%s%s%s%s%s.%s",
		DIR_TXT_OUT,DIR_TXT_REP,AUTOA_SCRIPT,CD_SUFFIXE,AUTOA_TRAD,AUTOA_ACCENTS,EXT_TXT);
	in_f=fopen(fich_nom_t,"r");

	// Réinsertion des accents
	if (orig_f==NULL || in_f==NULL)
		Main_Message_S("Script introuvable.\n","",ER);		
	else {
		// Chargement des infos
		AutoA_Charge(AUTOA_OUT);
		// Ouverture du fichier de sortie
		out_f=fopen(fich_nom,"w");
		// Recopie de l'entête du script
		for(i=0;i<4;i++) {
			fgets(ligne_o,AUTOA_LIGNE_MAX,orig_f);
			fgets(ligne_s,AUTOA_LIGNE_MAX,in_f);
			fputs(ligne_o,out_f);
		}
		fgets(ligne_o,AUTOA_LIGNE_MAX,orig_f);
		fgets(ligne_s,AUTOA_LIGNE_MAX,in_f);
		// Parcours du fichier
		while(!feof(orig_f)) {
			// Attente d'un bloc à traduire
			while(!feof(orig_f) && ligne_o[0]!=AUTOA_TRAD_CAR) {
				fputs(ligne_o,out_f);
				fgets(ligne_o,AUTOA_LIGNE_MAX,orig_f);
			}
			// Parcours du bloc d'origine
			do {
				fgets(ligne_o,AUTOA_LIGNE_MAX,orig_f);
			} while(!feof(orig_f) &&
				(ligne_o[0]==AUTOA_DEB_A || ligne_o[0]==AUTOA_DEB_1));
			if (!feof(in_f)) {
				// Informations de début de bloc
				fputs(ligne_s,out_f); // $ ...
				fgets(ligne_s,AUTOA_LIGNE_MAX,in_f);
				fputs(ligne_s,out_f); // +-...
				fgets(ligne_s,AUTOA_LIGNE_MAX,in_f);
				fputs(ligne_s,out_f); // Nom:
				fgets(ligne_s,AUTOA_LIGNE_MAX,in_f);
				// Parcours du bloc à réduire
				do {
					AutoA_Insere_Ligne(ligne_s,out_f);
					fgets(ligne_s,AUTOA_LIGNE_MAX,in_f);
				} while(!feof(in_f) && ligne_s[0]!=AUTOA_TRAD_CAR);
			}
		}
		// Fermeture des fichiers
		fclose(in_f);
		fclose(orig_f);
		fclose(out_f);
		// Ecrasement de l'ancien fichier
		remove(fich_nom_s);
		Main_OK();
	}
}